package asteroids.model;

import be.kuleuven.cs.som.annotate.*;
import asteroids.Util;

/**
 * A class representing an incoming collision between 2 space objects or between an object and a wall.
 * @invar The time before the collision happens is valid.
 * 			| Util.isValidDouble(getTimeToCollision())
 * @invar The first object must be a space object.
 * 			| getFirstObject() != null
 * @author Martin & Anton
 *
 */
public class Collision {
	
	private SpaceObject object1;
	private SpaceObject object2 = null;
	private double timeToCollision;
	private double x;
	private double y;
	
	public Collision(SpaceObject object1, SpaceObject object2, double timeToCollision) throws IllegalArgumentException{
		if(!Util.isValidDouble(timeToCollision) || object1==null)
			throw new IllegalArgumentException();
		this.object1 = object1;	
		this.object2 = object2;
		this.timeToCollision = timeToCollision;
		if(object2 != null){
			this.x = object1.getCollisionPosition(object2)[0];
			this.y = object1.getCollisionPosition(object2)[1];
		}
		else{
			this.x = object1.getBoundaryCollisionPosition()[0];
			this.y = object1.getBoundaryCollisionPosition()[1];
		}
	}
	
	@Basic
	public SpaceObject getFirstObject() {
		return object1;
	}
	
	@Basic
	public SpaceObject getSecondObject() {
		return object2;
	}
	
	@Basic
	public double getTimeToCollision(){
		return timeToCollision;
	}
	
	@Basic
	public double getX(){
		return x;
	}
	
	@Basic
	public double getY(){
		return y;
	}
	
	/**
	 * Subtracts the time from timeToCollision.
	 * @param time
	 * @post (new this).getTimeToCollision() = (this).getTimeToCollision() - time
	 * @throws IllegalArgumentException
	 * 			| if(!Util.isValidDouble(time) || time<0)
	 */
	public void substractTime(double time) throws IllegalArgumentException{
		if(!Util.isValidDouble(time) || Util.fuzzyLessThan(time, 0))
			throw new IllegalArgumentException();
		timeToCollision = timeToCollision - time;
	}
	
	/**
	 * Checks if this collision contains the object.
	 * @param object
	 * @return 
	 * 		| result == (getFirstObject() == object || getSecondObject() == object)
	 */
	public boolean contains(SpaceObject object){
		if(getFirstObject() == object || getSecondObject() == object)
			return true;
		else
			return false;
	}
	
	/**
	 * Checks if this collision contains one of the objects from the other.  
	 * @param collision
	 * @return True if one of the collisions' firstObjects is in both collisions.
	 * 			| if(getFirstObject() == collision.getFirstObject() || 
	 * 			| 	 getFirstObject() == collision.getSecondObject() ||
	 *			| 	 getSecondObject() == collision.getFirstObject())
	 * @return True if the collision's secondObjects are the same, except if they are 'null'
	 *			| if(getSecondObject() != null && getSecondObject() == collision.getSecondObject())		 
	 */
	public boolean containsAnObjectFrom(Collision collision){
		if(collision == null)
			return false;
		if(getFirstObject() == collision.getFirstObject() || getFirstObject() == collision.getSecondObject() ||
			getSecondObject() == collision.getFirstObject())
			return true;
		else if(getSecondObject() != null && getSecondObject() == collision.getSecondObject())
			return true;
		return false;
	}
	
}
